package tjs.study.notes.dotest.mongo.service;

import com.mongodb.client.result.UpdateResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tjs.study.notes.dotest.mongo.ClientA;
import tjs.study.notes.dotest.mongo.DkdTransactional;

import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;

/**
 * Created by Nicky.Tang on 2021/12/9 9:32 下午
 *
 * @since 02.12.10
 */
@Service
@DkdTransactional
public class UserMongoMapper {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Transactional
    public void countFor(int fori, Integer amount) {
        for (int i = 0; i < fori; i++) {
            long after = mongoTemplate.count(query(where("amount").is(amount)), UserMongo.class);
            System.out.println("after: " + after);
            ClientA.sleep(500l);
        }
    }

    @Transactional
    public void countForZ(int fori, Integer amount, String id) {
        ClientA.sleep(500l);
        for (int i = 0; i < 8; i++) {
            long after = mongoTemplate.count(query(where("amount").is(amount)), UserMongo.class);
            System.out.println(i + "after: " + after);
            ClientA.sleep(500l);
            if (i == 2) {
                Update update = new Update();
                update.set("name", i);
                UpdateResult result = mongoTemplate.updateFirst(query(where("_id").is(id)), update, UserMongo.class);
                // fixme 受影响行数：0 注意这里，和MySQl不一样哦
                System.out.println("受影响行数：" + result.getModifiedCount());
            }
        }
    }

    public long count(Integer amount) {
        return mongoTemplate.count(query(where("amount").is(amount)), UserMongo.class);
    }

    @Transactional
    public void save(UserMongo userMongo, Long sleepTime) {
        mongoTemplate.save(userMongo);
        ClientA.sleep(sleepTime);
        System.out.println("等待结束。。。");
    }

    @Transactional
    public void remove(String id, Long sleepTime) {
        mongoTemplate.remove(query(where("_id").is(id)), UserMongo.class);
        ClientA.sleep(sleepTime);
        System.out.println("等待结束。。。");
    }

    public UserMongo find(String id) {
        return mongoTemplate.findOne(query(where("_id").is(id)), UserMongo.class);
    }

    @Transactional
    public void resetName(String id, String name) {
        Update update = new Update();
        update.set("name", name);
        UpdateResult result = mongoTemplate.updateFirst(query(where("_id").is(id)), update, UserMongo.class);
        System.out.println("受影响行数：" + result.getModifiedCount());
    }

    @Transactional
    public void addAmount(String id, Integer amount, Long sleepTime, boolean throwEx) {
        Update update = new Update();
        update.inc("amount", amount);
        mongoTemplate.findAndModify(query(where("_id").is(id)), update,
                new FindAndModifyOptions().upsert(true).returnNew(true), UserMongo.class);

        ClientA.sleep(sleepTime);
        System.out.println("等待结束。。。");
        if (throwEx) {
            throw new RuntimeException("测试回滚");
        }
    }

}
